package com.kaizeli.website.controller;

import com.kaizeli.website.pojo.dto.base.PageDTO;
import com.kaizeli.website.pojo.model.EmployeeDO;
import com.kaizeli.website.pojo.vo.EmployeeVO;
import com.kaizeli.website.query.EmployeeQuery;
import com.kaizeli.website.response.Result;
import com.kaizeli.website.service.impl.EmployeeSimpleServiceImpl;
import io.swagger.v3.oas.annotations.Operation;
import io.swagger.v3.oas.annotations.Parameter;
import io.swagger.v3.oas.annotations.tags.Tag;
import lombok.RequiredArgsConstructor;
import org.springframework.util.StringUtils;
import org.springframework.web.bind.annotation.*;

import java.util.List;
import java.util.regex.Pattern;

/**
 * 员工管理控制器
 */
@RestController
@RequestMapping("/api/employee")
@RequiredArgsConstructor
@Tag(name = "员工管理", description = "员工信息的增删改查接口")
public class EmployeeController {
    
    private final EmployeeSimpleServiceImpl employeeService;
    
    /**
     * 分页查询员工列表
     */
    @PostMapping("/page")
    @Operation(summary = "分页查询员工列表", description = "根据条件分页查询员工信息")
    public Result<PageDTO<EmployeeVO>> pageQuery(@RequestBody EmployeeQuery query) {
        PageDTO<EmployeeVO> result = employeeService.pageQuery(query);
        return Result.success(result);
    }
    
    /**
     * 根据ID查询员工详情
     */
    @GetMapping("/{id}")
    @Operation(summary = "查询员工详情", description = "根据员工ID查询员工详细信息")
    public Result<EmployeeVO> getById(@Parameter(description = "员工ID") @PathVariable Long id) {
        EmployeeVO result = employeeService.getById(id);
        return Result.success(result);
    }
    
    /**
     * 根据员工编号查询员工详情
     */
    @GetMapping("/code/{employeeCode}")
    @Operation(summary = "根据员工编号查询", description = "根据员工编号查询员工详细信息")
    public Result<EmployeeVO> getByEmployeeCode(@Parameter(description = "员工编号") @PathVariable String employeeCode) {
        EmployeeVO result = employeeService.getByEmployeeCode(employeeCode);
        return Result.success(result);
    }
    
    /**
     * 新增员工
     */
    @PostMapping
    @Operation(summary = "新增员工", description = "创建新的员工信息")
    public Result<Long> save(@RequestBody EmployeeDO employeeDO) {
        try {
            Long id = employeeService.save(employeeDO);
            return Result.success(id);
        } catch (Exception e) {
            return Result.error(500, "保存员工信息失败: " + e.getMessage());
        }
    }
    
    /**
     * 公开接口：问卷提交（不需要登录）
     * 🔒 安全措施：输入验证、SQL注入防护、XSS防护
     */
    @PostMapping("/public/questionnaire")
    @Operation(summary = "问卷提交（公开接口）", description = "员工入职信息问卷提交，不需要认证但包含安全验证")
    public Result<Long> submitQuestionnaire(@RequestBody EmployeeDO employeeDO) {
        try {
            // 🔒 安全措施1: 输入验证
            if (!validateQuestionnaireInput(employeeDO)) {
                return Result.error(400, "输入验证失败，请检查填写的信息");
            }
            
            // 🔒 安全措施2: 防止SQL注入和XSS攻击
            sanitizeEmployeeInput(employeeDO);
            
            // 调用保存方法
            Long id = employeeService.save(employeeDO);
            return Result.success(id);
        } catch (Exception e) {
            return Result.error(500, "提交失败: " + e.getMessage());
        }
    }
    
    /**
     * 🔒 验证问卷输入数据
     */
    private boolean validateQuestionnaireInput(EmployeeDO employeeDO) {
        // 验证必填字段
        if (!StringUtils.hasText(employeeDO.getName()) || employeeDO.getName().length() < 2 || employeeDO.getName().length() > 50) {
            return false;
        }
        
        if (!StringUtils.hasText(employeeDO.getPhone()) || !isValidPhone(employeeDO.getPhone())) {
            return false;
        }
        
        if (!StringUtils.hasText(employeeDO.getEmail()) || !isValidEmail(employeeDO.getEmail())) {
            return false;
        }
        
        // 验证身份证号（如果提供）
        if (StringUtils.hasText(employeeDO.getIdCard()) && !isValidIdCard(employeeDO.getIdCard())) {
            return false;
        }
        
        return true;
    }
    
    /**
     * 🔒 清理输入数据，防止SQL注入和XSS攻击
     */
    private void sanitizeEmployeeInput(EmployeeDO employeeDO) {
        // 清理字符串字段，移除危险字符
        if (StringUtils.hasText(employeeDO.getName())) {
            employeeDO.setName(sanitizeString(employeeDO.getName(), 50));
        }
        if (StringUtils.hasText(employeeDO.getPhone())) {
            employeeDO.setPhone(sanitizeString(employeeDO.getPhone(), 20));
        }
        if (StringUtils.hasText(employeeDO.getEmail())) {
            employeeDO.setEmail(sanitizeString(employeeDO.getEmail(), 100));
        }
        if (StringUtils.hasText(employeeDO.getIdCard())) {
            employeeDO.setIdCard(sanitizeString(employeeDO.getIdCard(), 18));
        }
        if (StringUtils.hasText(employeeDO.getRegisteredAddress())) {
            employeeDO.setRegisteredAddress(sanitizeString(employeeDO.getRegisteredAddress(), 500));
        }
        if (StringUtils.hasText(employeeDO.getCurrentAddress())) {
            employeeDO.setCurrentAddress(sanitizeString(employeeDO.getCurrentAddress(), 500));
        }
        if (StringUtils.hasText(employeeDO.getMajor())) {
            employeeDO.setMajor(sanitizeString(employeeDO.getMajor(), 100));
        }
        if (StringUtils.hasText(employeeDO.getUniversity())) {
            employeeDO.setUniversity(sanitizeString(employeeDO.getUniversity(), 200));
        }
        if (StringUtils.hasText(employeeDO.getEmergencyContact())) {
            employeeDO.setEmergencyContact(sanitizeString(employeeDO.getEmergencyContact(), 100));
        }
        if (StringUtils.hasText(employeeDO.getEmergencyPhone())) {
            employeeDO.setEmergencyPhone(sanitizeString(employeeDO.getEmergencyPhone(), 20));
        }
        if (StringUtils.hasText(employeeDO.getBankAccount())) {
            employeeDO.setBankAccount(sanitizeString(employeeDO.getBankAccount(), 50));
        }
        if (StringUtils.hasText(employeeDO.getBankName())) {
            employeeDO.setBankName(sanitizeString(employeeDO.getBankName(), 100));
        }
        if (StringUtils.hasText(employeeDO.getSkillCertificates())) {
            employeeDO.setSkillCertificates(sanitizeString(employeeDO.getSkillCertificates(), 500));
        }
    }
    
    /**
     * 清理字符串，移除危险字符
     */
    private String sanitizeString(String input, int maxLength) {
        if (!StringUtils.hasText(input)) {
            return input;
        }
        
        // 移除HTML标签和JavaScript
        String sanitized = input
            .replaceAll("<[^>]*>", "")  // 移除HTML标签
            .replaceAll("javascript:", "")  // 移除javascript协议
            .replaceAll("on\\w+=", "")  // 移除事件处理器
            .replaceAll("[<>\"'&]", "")  // 移除危险字符
            .trim();
        
        // 限制长度
        if (sanitized.length() > maxLength) {
            sanitized = sanitized.substring(0, maxLength);
        }
        
        return sanitized;
    }
    
    /**
     * 验证手机号格式
     */
    private boolean isValidPhone(String phone) {
        if (!StringUtils.hasText(phone)) {
            return false;
        }
        Pattern pattern = Pattern.compile("^1[3-9]\\d{9}$");
        return pattern.matcher(phone).matches();
    }
    
    /**
     * 验证邮箱格式
     */
    private boolean isValidEmail(String email) {
        if (!StringUtils.hasText(email)) {
            return false;
        }
        Pattern pattern = Pattern.compile("^[A-Za-z0-9+_.-]+@[A-Za-z0-9.-]+\\.[A-Za-z]{2,}$");
        return pattern.matcher(email).matches();
    }
    
    /**
     * 验证身份证号格式
     */
    private boolean isValidIdCard(String idCard) {
        if (!StringUtils.hasText(idCard)) {
            return false;
        }
        Pattern pattern = Pattern.compile("^[1-9]\\d{5}(18|19|20)\\d{2}(0[1-9]|1[0-2])(0[1-9]|[1-2][0-9]|3[0-1])\\d{3}[0-9Xx]$");
        return pattern.matcher(idCard).matches();
    }
    
    /**
     * 更新员工信息
     */
    @PutMapping
    @Operation(summary = "更新员工信息", description = "更新员工的详细信息")
    public Result<Boolean> update(@RequestBody EmployeeDO employeeDO) {
        Boolean result = employeeService.update(employeeDO);
        return Result.success(result);
    }
    
    /**
     * 删除员工
     */
    @DeleteMapping("/{id}")
    @Operation(summary = "删除员工", description = "根据员工ID删除员工信息")
    public Result<Boolean> deleteById(@Parameter(description = "员工ID") @PathVariable Long id) {
        Boolean result = employeeService.deleteById(id);
        return Result.success(result);
    }
    
    /**
     * 批量删除员工
     */
    @DeleteMapping("/batch")
    @Operation(summary = "批量删除员工", description = "根据员工ID列表批量删除员工信息")
    public Result<Boolean> deleteBatchByIds(@RequestBody List<Long> ids) {
        Boolean result = employeeService.deleteBatchByIds(ids);
        return Result.success(result);
    }
    
    /**
     * 更新员工状态
     */
    @PutMapping("/{id}/status/{status}")
    @Operation(summary = "更新员工状态", description = "更新员工的在职状态")
    public Result<Boolean> updateStatus(
            @Parameter(description = "员工ID") @PathVariable Long id,
            @Parameter(description = "员工状态：1-在职，0-离职") @PathVariable Integer status) {
        Boolean result = employeeService.updateStatus(id, status);
        return Result.success(result);
    }
    
    /**
     * 根据员工状态查询员工列表
     */
    @GetMapping("/status/{status}")
    @Operation(summary = "根据状态查询员工", description = "根据员工状态查询员工列表")
    public Result<List<EmployeeVO>> getEmployeesByStatus(
            @Parameter(description = "员工状态：1-在职，0-离职") @PathVariable Integer status) {
        List<EmployeeVO> result = employeeService.getEmployeesByStatus(status);
        return Result.success(result);
    }
    
    /**
     * 搜索员工
     */
    @GetMapping("/search")
    @Operation(summary = "搜索员工", description = "根据姓名或编号搜索员工信息")
    public Result<List<EmployeeVO>> search(
            @Parameter(description = "搜索关键词（员工姓名或编号）", required = true, example = "张三")
            @RequestParam String keyword) {
        List<EmployeeVO> result = employeeService.search(keyword);
        return Result.success(result);
    }
    
    /**
     * 获取所有在职员工列表
     */
    @GetMapping("/active")
    @Operation(summary = "获取所有在职员工列表", description = "获取所有在职员工列表（用于选择）")
    public Result<List<EmployeeVO>> getAllActiveEmployees() {
        List<EmployeeVO> result = employeeService.getEmployeesByStatus(1);
        return Result.success(result);
    }
    
    /**
     * 获取所有员工列表
     */
    @GetMapping("/all")
    @Operation(summary = "获取所有员工列表", description = "获取所有员工列表（用于选择）")
    public Result<List<EmployeeVO>> getAllEmployees() {
        List<EmployeeVO> result = employeeService.getAllEmployees();
        return Result.success(result);
    }
}